package strategy

import (
	"adam2/internal/domain"
	"adam2/internal/quant/impl/buy"
	"adam2/internal/quant/impl/filter"
	qImpl "adam2/internal/quant/impl/log"
	"adam2/internal/quant/impl/prepare_data"
	"adam2/internal/quant/impl/sell"
	"adam2/internal/quant/impl/transaction_date"
	"adam2/internal/quant/impl/update_quant_account"
	_interface "adam2/internal/quant/interface"
	"adam2/internal/quant/step"
	"anubis-framework/pkg/io"
)

// 最小21日内涨跌策略
type MinUpDownPercentage21Strategy struct {
	transactionDateStep              *step.TransactionDateStep
	updateQuantAccountBeforeSellStep *step.UpdateQuantAccountBeforeSellStep
	sellStep                         *step.SellStep
	updateQuantAccountAfterSellStep  *step.UpdateQuantAccountAfterSellStep
	prepareDataStep                  *step.PrepareDataStep
	filterStep                       *step.FilterStep
	buyStep                          *step.BuyStep
	updateQuantAccountAfterBuyStep   *step.UpdateQuantAccountAfterBuyStep
	commonLogStep                    *step.CommonLogStep
}

// 初始化
func (m *MinUpDownPercentage21Strategy) init(transactionDateStep *step.TransactionDateStep,
	updateQuantAccountBeforeSellStep *step.UpdateQuantAccountBeforeSellStep, sellStep *step.SellStep,
	updateQuantAccountAfterSellStep *step.UpdateQuantAccountAfterSellStep, prepareDataStep *step.PrepareDataStep,
	filterStep *step.FilterStep, buyStep *step.BuyStep, updateQuantAccountAfterBuyStep *step.UpdateQuantAccountAfterBuyStep,
	commonLogStep *step.CommonLogStep) {
	m.transactionDateStep = transactionDateStep
	m.updateQuantAccountBeforeSellStep = updateQuantAccountBeforeSellStep
	m.sellStep = sellStep
	m.updateQuantAccountAfterSellStep = updateQuantAccountAfterSellStep
	m.prepareDataStep = prepareDataStep
	m.filterStep = filterStep
	m.buyStep = buyStep
	m.updateQuantAccountAfterBuyStep = updateQuantAccountAfterBuyStep
	m.commonLogStep = commonLogStep
}

// 配置策略
func (m *MinUpDownPercentage21Strategy) ConfigStrategy() {
	// 初始化ManyTransactionDate
	var manyTransactionDate _interface.TransactionDate = &transaction_date.ManyTransactionDate{}
	manyTransactionDate.Init(domain.DataSource_.GormDb)
	// 初始化TransactionDateStep
	var transactionDateStep step.TransactionDateStep = step.TransactionDateStep{}
	transactionDateStep.Init(&manyTransactionDate)

	// 初始化MonthBeginningSellDate
	var monthBeginningSellDate _interface.SellDate = &transaction_date.MonthBeginningSellDate{}
	monthBeginningSellDate.Init(domain.DataSource_.GormDb)
	// 初始化MonthBeginningBuyDate
	var monthBeginningBuyDate _interface.BuyDate = &transaction_date.MonthBeginningBuyDate{}
	monthBeginningBuyDate.Init(domain.DataSource_.GormDb)
	// 初始化MonthEndStatisticsDate
	var monthEndStatisticsDate _interface.StatisticsDate = &transaction_date.MonthEndStatisticsDate{}
	monthEndStatisticsDate.Init(domain.DataSource_.GormDb)

	// 初始化UpdateQuantAccountBeforeSell
	var updateQuantAccountBeforeSell _interface.UpdateQuantAccount = &update_quant_account.UpdateQuantAccountBeforeSell{}
	updateQuantAccountBeforeSell.Init(domain.DataSource_.GormDb)
	// 初始化UpdateQuantAccountBeforeSellStep
	var updateQuantAccountBeforeSellStep step.UpdateQuantAccountBeforeSellStep = step.UpdateQuantAccountBeforeSellStep{}
	updateQuantAccountBeforeSellStep.Init(&updateQuantAccountBeforeSell, &monthBeginningSellDate)

	// 初始化CommonSell
	var commonSell _interface.Sell = &sell.CommonSell{}
	commonSell.Init(domain.DataSource_.GormDb)
	// 初始化CommonDelistSell
	var commonDelistSell _interface.Sell = &sell.CommonDelistSell{}
	commonDelistSell.Init(domain.DataSource_.GormDb)
	// 初始化CommonResolveFailSell
	var commonResolveFailSell _interface.Sell = &sell.CommonResolveFailSell{}
	commonResolveFailSell.Init(domain.DataSource_.GormDb)
	// 初始化SellStep
	var sellStep step.SellStep = step.SellStep{}
	sellStep.Init(&commonSell, &commonDelistSell, &commonResolveFailSell, &monthBeginningSellDate)

	// 初始化UpdateQuantAccountAfterSell
	var updateQuantAccountAfterSell _interface.UpdateQuantAccount = &update_quant_account.UpdateQuantAccountAfterSell{}
	updateQuantAccountAfterSell.Init(domain.DataSource_.GormDb)
	// 初始化UpdateQuantAccountAfterSellStep
	var updateQuantAccountAfterSellStep step.UpdateQuantAccountAfterSellStep = step.UpdateQuantAccountAfterSellStep{}
	updateQuantAccountAfterSellStep.Init(&monthBeginningSellDate, &updateQuantAccountAfterSell)

	// 初始化MinUpDownPercentage21PrepareData
	var minUpDownPercentage21PrepareData _interface.PrepareData = &prepare_data.MinUpDownPercentage21PrepareData{}
	minUpDownPercentage21PrepareData.Init(domain.DataSource_.GormDb)
	// 初始化PrepareDataStep
	var prepareDataStep step.PrepareDataStep = step.PrepareDataStep{}
	prepareDataStep.Init(&minUpDownPercentage21PrepareData, &monthEndStatisticsDate)

	// 初始化FilterStep
	var filterStep step.FilterStep = step.FilterStep{}
	filterStep.Init(&monthBeginningBuyDate, &monthEndStatisticsDate)
	// 初始化TotalMarketValueBottomLimitFilter
	//var totalMarketValueBottomLimitFilter _interface.Filter = &filter.TotalMarketValueBottomLimitFilter{}
	//totalMarketValueBottomLimitFilter.Init(domain.DataSource_.GormDb)
	//filterStep.AddStatisticsDateFilter(&totalMarketValueBottomLimitFilter)
	// 初始化TenLowestUpDownPercentage21Filter
	var tenLowestUpDownPercentage21Filter _interface.Filter = &filter.TenLowestUpDownPercentage21Filter{}
	tenLowestUpDownPercentage21Filter.Init(domain.DataSource_.GormDb)
	filterStep.AddStatisticsDateFilter(&tenLowestUpDownPercentage21Filter)
	// 初始化OneWordLimitUpFilter
	var oneWordLimitUpFilter _interface.Filter = &filter.OneWordLimitUpFilter{}
	oneWordLimitUpFilter.Init(domain.DataSource_.GormDb)
	filterStep.AddBuyDateFilter(&oneWordLimitUpFilter)
	// 初始化OpenPriceBottomLimitFilter
	//var openPriceBottomLimitFilter _interface.Filter = &filter.OpenPriceBottomLimitFilter{}
	//openPriceBottomLimitFilter.Init(domain.DataSource_.GormDb)
	//filterStep.AddBuyDateFilter(&openPriceBottomLimitFilter)

	// 初始化CommonBuy
	var commonBuy _interface.Buy = &buy.CommonBuy{}
	commonBuy.Init(domain.DataSource_.GormDb)
	// 初始化BuyStep
	var buyStep step.BuyStep = step.BuyStep{}
	buyStep.Init(&commonBuy, &monthBeginningBuyDate)

	// 初始化UpdateQuantAccountAfterBuy
	var updateQuantAccountAfterBuy _interface.UpdateQuantAccount = &update_quant_account.UpdateQuantAccountAfterBuy{}
	updateQuantAccountAfterBuy.Init(domain.DataSource_.GormDb)
	// 初始化UpdateQuantAccountAfterBuyStep
	var updateQuantAccountAfterBuyStep step.UpdateQuantAccountAfterBuyStep = step.UpdateQuantAccountAfterBuyStep{}
	updateQuantAccountAfterBuyStep.Init(&monthBeginningBuyDate, &updateQuantAccountAfterBuy)

	// 初始化CommonLog
	var commonLog _interface.Log = &qImpl.CommonLog{}
	commonLog.Init(domain.DataSource_.GormDb)
	// 初始化CommonLogStep
	var commonLogStep step.CommonLogStep = step.CommonLogStep{}
	commonLogStep.Init(&commonLog)

	// 初始化MinUpDownPercentage21Strategy
	m.init(&transactionDateStep, &updateQuantAccountBeforeSellStep, &sellStep, &updateQuantAccountAfterSellStep,
		&prepareDataStep, &filterStep, &buyStep, &updateQuantAccountAfterBuyStep, &commonLogStep)
}

// 开始
func (m *MinUpDownPercentage21Strategy) Start() {
	// 查询交易日期
	var transactionDateArray []string = m.transactionDateStep.Exec()
	if transactionDateArray != nil && len(transactionDateArray) > 0 {
		for _, transactionDate := range transactionDateArray {
			// 每日---卖出之前更新quant_account
			m.updateQuantAccountBeforeSellStep.UpdateQuantAccountBeforeSellStep(transactionDate)

			// 统计日---准备数据
			m.prepareDataStep.Exec(transactionDate)

			// 统计日、买入日---过滤股票
			m.filterStep.Exec(transactionDate)

			// 卖出日---卖出
			m.sellStep.Exec(transactionDate)

			// 卖出日---在卖出之后更新quant_account
			m.updateQuantAccountAfterSellStep.UpdateQuantAccountAfterSell(transactionDate)

			// 买入日---买入
			m.buyStep.Exec(transactionDate)

			// 买入日---在买入之后更新quant_account表
			m.updateQuantAccountAfterBuyStep.UpdateQuantAccountAfterBuy(transactionDate)

			// 每日---向表quant_account_log中插入记录
			m.commonLogStep.Exec(transactionDate)
		}
	} else {
		io.Infoln("交易日期为空，程序结束")
	}
}
